package com.itfenghuang.day02;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public class A02_jdbc事务 {
    /**
     * 使用jdbc去操作事务
     *  事务:将一组操作作为一个整体,要么同时成功,要么同时失败
     *  四大特性:
     *      1).原子性:整个事务是一个不可分割的整体,这个整体要么同时成功,要么同时失败
     * 	    2).一致性:事务前后一致性状态不能发生改变
     * 	    3).隔离性:多个事务并发操作数据的时候是相互隔离的
     * 	    4).持久性:数据会持久化到介质上,数据的更改是永久性的
     * 	隔离级别:
     * 	    1.串行化: 排队 不会出问题 效率低
     * 	    2.读未提交: 可以读取其他事务没有提交的数据 	/脏读 不可重复读 	幻读
     * 	    3.读已提交: 只能读已经提交的数据	/不可重复读 	幻读
     * 	    4.可重复读: 前后多次读的数据必须一样  /幻读 (mysql默认的隔离级别)
     *
     *  事务的两种状态:
     *      提交,回滚
     *  jdbc也能管理事务: 使用连接对象 connection
     *      管理事务前提条件:
     *      如果使用jdbc管理事务,必须保证是同一个连接对象
     */
    public static void main(String[] args) throws Exception{
        Class.forName("com.mysql.jdbc.Driver");
        Connection conn = DriverManager.getConnection
                ("jdbc:mysql://127.0.0.1:3306/aa_chun_day02", "root", "123456");
        //批量插入数据
        //需求:让这两条数据一块执行,如果有异常,全部不执行
        //开启事务 void setAutoCommit(boolean autoCommit)
        //autoCommit参数,如果是false,需要手动提交事务,开启事务  如果ture,自动提交事务
        try {
            conn.setAutoCommit(false);//设置是否自动提交事务
            for (int i=0;i<2;i++) {
                //管理事务前提条件:要保证连接对象是同一个
                insert(conn);
                insert(conn);
//                System.out.println(2/0);
            }
            conn.commit();//提交事务
        } catch (SQLException e) {
            e.printStackTrace();
            conn.rollback();//事务回滚
        }finally {
            conn.close();
        }
    }

    private static void insert(Connection conn) throws SQLException {
        PreparedStatement pstate =
                conn.prepareStatement("insert into user(username,password) value(?,?)");
        pstate.setString(1,"rose");
        pstate.setInt(2,222);
        pstate.executeUpdate();
        //释放资源
        pstate.close();
    }
}
